#
#   Character.py
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; version 2 of the License.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   Copyright
#   Author: Nicholas F. Hoover
#   Contributors: Salvatore S. Gionfriddo
#   Created: 2007.06.30
#   Last Modified: 2007.11.03
#

import pygame
from GameObject import GameObject

class Character(GameObject):
    """This is a GameObject with heatlh and effects"""
    
    MIN_HEALTH = 0
    MAX_HEALTH = 100

    LOCKED_TO_SCREEN = True
    MOVE = True

    AVERT = False

    def __init__(self):
        GameObject.__init__(self)
        self.reset()
        
    def incHealth(self,amount):
        self.health += amount
        if self.health > self.MAX_HEALTH: self.health = self.MAX_HEALTH
        
    def decHealth(self,amount):
        self.health -= amount
        if self.health < self.MIN_HEALTH: self.health = self.MIN_HEALTH        

    def isAlive(self):
        return self.health > self.MIN_HEALTH

    def reset(self):
        GameObject.reset(self)
        self.health = self.MAX_HEALTH

    def move(self, amount, collision = None, avert = False):
        (x,y) = amount

        if collision:
            collision = collision[:]
            collision.remove(self.collision_rect)
        else:
            self.setPosition((self.rect.left + x, self.rect.top + y))
            return
        
        #set choices
        choices = [(x,y), (x,0), (0,y), (-x,y), (x,-y)]
        
        #check collisions
        i = 0
        for (x,y) in choices:            
            new_col_rect = pygame.Rect(self.collision_rect)
            new_col_rect.left += x
            new_col_rect.top += y
        
            i += 1
            if collision:
                collide = new_col_rect.collidelist(collision)
                if collide < 0:
                    self.setPosition((self.rect.left + x, self.rect.top + y))
                    if self.collision_rect.collidelist(collision) >= 0: print 'WTF'
                    break
            if not avert:
                break

    def addEffect(self, effect):
        #apply instant effect
        if effect.i_change:
            self.__class__.__dict__[effect.i_change](self, effect.i_change_amount)
        #add to effect list
        self.effects.append(effect)

                
    def doEffects(self):
        for effect in self.effects[:]:
            #check effect age
            if effect.age >= effect.life:
                #apply end effect
                if effect.e_change:
                    self.__class__.__dict__[effect.e_change](self, effect.e_change_amount)
                #remove from effect list
                self.effects.remove(effect)
            else:
                #increment effect age
                effect.age += 1
                #apply durational effect
                if effect.change:
                    self.__class__.__dict__[effect.change](self, effect.change_amount)

    def performAI(self, collision, targetRect):
        pass

    
    def update(self, collision = None, evilGregRect = 0):
        self.updateAttached()
        if self.updateCurrentAnimation():
            for action in self.ACTIONS:
                self.checkForStopAction(action)

            #update the image to be displayed
            self.performAI(collision, evilGregRect)
            self.updateCurrentImage()

            #I like to move it, move it. Move it, move it.
            #HACK
            movement = self.MOVEMENTS[self.getAnimationType()]
            if self.currentAnimation == self.WALK_SIDE + self.LEFT:
                movement = (-movement[0], movement[1])
            (x,y) = (self.rect.left,self.rect.top)
            
            #calculate speed bonus
            if movement[0] > 0: mx = movement[0] + self.speed_bonus
            elif movement[0] < 0: mx =  movement[0] - self.speed_bonus
            else: mx = 0
            
            if movement[1] > 0: my = movement[1] + self.speed_bonus
            elif movement[1] < 0: my =  movement[1] - self.speed_bonus
            else: my = 0
            
            #apply movement
            if self.LOCKED_TO_SCREEN:
                if self.rect.right + mx <= 825 and self.rect.left + mx >= -25: # mad hax
                    mx = mx
                else:
                    mx = 0
                if self.rect.bottom + my <= 625 and self.rect.top + my >= -25: # mad hax
                    my =  my
                else:
                    my = 0
            if self.MOVE:
                self.move((mx,my), collision, self.AVERT)

            self.doStatusUpdate()

    def attack1(self):
        if self.canAct():
            self.setAnimation(self.ATTACK1)

    def attack2(self):
        if self.canAct():
            self.setAnimation(self.ATTACK2)

    def canAct(self):
        return self.currentAnimation - self.facing <= self.WALK_SIDE
            
    def startIdling(self):
        self.setAnimation(self.IDLE)
        
    def checkForStopAction(self, action):
        if self.isActionComplete(action):
            self.doNextAction()
            
    def doNextAction(self):
        self.facing = self.nextFacing
        self.setAnimation(self.nextAction)
        
    def clearNextAction(self):
        self.nextAction = self.IDLE
        self.nextFacing = self.facing
        self.doNextAction()

    def doStatusUpdate(self):
        pass

    def walk(self,direction, facing = None):
        if self.canAct():
            self.setAnimation(direction, facing)
        if facing != None: self.nextFacing = facing
        else: self.nextFacing = self.facing
        self.nextAction = direction

    def stopWalk(self, direction, facing = None):
        self.nextAction = self.IDLE
        self.nextFacing = self.facing
        if facing == None: facing = self.facing
        if self.currentAnimation == direction + facing:
            self.startIdling()
